<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--

Generated from manual.tex by tex2page, v 20050501
(running on MzScheme 299.400, unix), 
(c) Dorai Sitaram, 
http://www.ccs.neu.edu/~dorai/tex2page/tex2page-doc.html

-->
<head>
<title>
The Incomplete Scheme 48 Reference Manual for release 1.6
</title>
<link rel="stylesheet" type="text/css" href="manual-Z-S.css" title=default>
<meta name=robots content="noindex,follow">
</head>
<body>
<div id=content>
<div align=right class=navigation><i>[Go to <span><a href="manual.html">first</a>, <a href="manual-Z-H-9.html">previous</a></span><span>, <a href="manual-Z-H-11.html">next</a></span> page<span>; &nbsp;&nbsp;</span><span><a href="manual-Z-H-2.html#node_toc_start">contents</a></span><span><span>; &nbsp;&nbsp;</span><a href="manual-Z-H-13.html#node_index_start">index</a></span>]</i></div>
<p></p>
<a name="node_chap_8"></a>
<h1 class=chapter>
<div class=chapterheading><a href="manual-Z-H-2.html#node_toc_node_chap_8">Chapter 8</a></div><br>
<a href="manual-Z-H-2.html#node_toc_node_chap_8">Mixing Scheme 48 and C</a></h1>
<p></p>
<p>
This chapter describes an interface for calling C functions
from Scheme, calling Scheme functions from C, and allocating
storage in the Scheme heap..
Scheme&nbsp;48 manages stub functions in C that
negotiate between the calling conventions of Scheme and C and the
memory allocation policies of both worlds.
No stub generator is available yet, but writing stubs is a straightforward task.</p>
<p>
</p>
<a name="node_sec_8.1"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.1">8.1&nbsp;&nbsp;Available facilities</a></h2>
<p></p>
<p>
The following facilities are available for interfacing between
Scheme&nbsp;48 and C:
</p>
<ul>
<li><p>Scheme code can call C functions.
</p>
<li><p>The external interface provides full introspection for all
Scheme objects.  External code may inspect, modify, and allocate
Scheme objects arbitrarily.
</p>
<li><p>External code may raise exceptions back to Scheme&nbsp;48 to
signal errors.
</p>
<li><p>External code may call back into Scheme.  Scheme&nbsp;48
correctly unrolls the process stack on non-local exits.
</p>
<li><p>External modules may register bindings of names to values with a 
central registry accessible from
Scheme.  Conversely, Scheme code can register shared
bindings for access by C code.
</p>
</ul><p>
</p>
<p>
</p>
<a name="node_sec_8.1.1"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.1.1">8.1.1&nbsp;&nbsp;Scheme structures</a></h3>
<p>The structure <tt>external-calls</tt> has 
most of the Scheme functions described here.
The others are in 
<tt>dynamic-externals</tt>, which has the functions for dynamic loading and
name lookup from
Section&nbsp;<a href="#node_sec_8.4">8.4</a>,
and <tt>shared-bindings</tt>, which has the additional shared-binding functions
described in
section&nbsp;<a href="#node_sec_8.2.3">8.2.3</a>.</p>
<p>
</p>
<a name="node_sec_8.1.2"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.1.2">8.1.2&nbsp;&nbsp;C naming conventions</a></h3>
<p>The names of all of Scheme&nbsp;48's visible C bindings begin 
with `<tt>s48_</tt>' (for procedures and variables) or 
`<tt>S48_</tt>' (for macros).
Whenever a C name is derived from a Scheme identifier, we
replace `<tt>-</tt>' with `<tt>_</tt>' and convert letters to lowercase
for procedures and uppercase for macros.
A final `<tt>?</tt>'  converted to `<tt>_p</tt>' (`<tt>_P</tt>' in C macro names).
A final `<tt>!</tt>' is dropped.
Thus the C macro for Scheme's <tt>pair?</tt> is <tt>S48_PAIR_P</tt> and
the one for <tt>set-car!</tt> is <tt>S48_SET_CAR</tt>.
Procedures and macros that do not check the types of their arguments
have `<tt>unsafe</tt>' in their names.</p>
<p>
All of the C functions and macros described have prototypes or definitions
in the file <tt>c/scheme48.h</tt>.
The C type for Scheme values is defined there to be <tt>s48_value</tt>.</p>
<p>
</p>
<a name="node_sec_8.1.3"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.1.3">8.1.3&nbsp;&nbsp;Garbage collection</a></h3>
<p>Scheme&nbsp;48 uses a copying garbage collector.
The collector must be able to locate all references
to objects allocated in the Scheme&nbsp;48 heap in order to ensure that
storage is not reclaimed prematurely and to update references to objects
moved by the collector.
The garbage collector may run whenever an object is allocated in the heap.
C variables whose values are Scheme&nbsp;48 objects and which are live across
heap allocation calls need to be registered with
the
garbage collector.  See section&nbsp;<a href="#node_sec_8.8">8.8</a> for more information.</p>
<p>
</p>
<a name="node_sec_8.2"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.2">8.2&nbsp;&nbsp;Shared bindings</a></h2>
<p></p>
<p>
Shared bindings are the means by which named values are shared between Scheme
code and C code.
There are two separate tables of shared bindings, one for values defined in
Scheme and accessed from C and the other for values going the other way.
Shared bindings actually bind names to cells, to allow a name to be looked
up before it has been assigned.
This is necessary because C initialization code may be run before or after
the corresponding Scheme code, depending on whether the Scheme code is in
the resumed image or is run in the current session.</p>
<p>
</p>
<a name="node_sec_8.2.1"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.2.1">8.2.1&nbsp;&nbsp;Exporting Scheme values to C</a></h3>
<p></p>
<ul>
<li><p><tt>(define-exported-binding<i> name value</i>)&nbsp;-&gt;&nbsp;<i>shared-binding</i></tt><a name="node_idx_650"></a>
</p>
</ul><p></p>
<p>
</p>
<ul>
<li><p><tt>s48_value s48_get_imported_binding(char *name)</tt>
</p>
<li><p><tt>s48_value S48_SHARED_BINDING_REF(s48_value shared_binding)</tt>
</p>
</ul><p></p>
<p>
<tt>Define-exported-binding</tt> makes <i>value</i> available to C code
under as <i>name</i> which must be a <i>string</i>, creating a new shared
binding if necessary.
The C function <tt>s48_get_imported_binding</tt> returns the shared binding
defined for <tt>name</tt>, again creating it if necessary.
The C macro <tt>S48_SHARED_BINDING_REF</tt> dereferences a shared binding,
returning its current value.</p>
<p>
</p>
<a name="node_sec_8.2.2"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.2.2">8.2.2&nbsp;&nbsp;Exporting C values to Scheme</a></h3>
<p></p>
<ul>
<li><p><tt>void s48_define_exported_binding(char *name, s48_value v)</tt>
</p>
</ul><p></p>
<p>
</p>
<ul>
<li><p><tt>(lookup-imported-binding<i> string</i>)&nbsp;-&gt;&nbsp;<i>shared-binding</i></tt><a name="node_idx_652"></a>
</p>
<li><p><tt>(shared-binding-ref<i> shared-binding</i>)&nbsp;-&gt;&nbsp;<i>value</i></tt><a name="node_idx_654"></a>
</p>
</ul><p></p>
<p>
These are used to define shared bindings from C and to access them
from Scheme.
Again, if a name is looked up before it has been defined, a new binding is
created for it.</p>
<p>
The common case of exporting a C function to Scheme can be done using
the macro <tt>S48_EXPORT_FUNCTION(<i>name</i>)</tt>.
This expands into
</p>
<pre class=verbatim>s48_define_exported_binding(&quot;<i>name</i>&quot;,
                               s48_enter_pointer(<i>name</i>))
</pre><p></p>
<p>
which boxes the function into a Scheme byte vector and then
exports it.
Note that <tt>s48_enter_pointer</tt> allocates space in the Scheme heap
and might trigger a 
garbage collection; see Section&nbsp;<a href="#node_sec_8.8">8.8</a>.</p>
<p>
</p>
<ul>
<li><p><tt>(import-definition <i>name</i>)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(syntax)<a name="node_idx_656"></a>
</p>
<li><p><tt>(import-definition <i>name c-name</i>)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(syntax)
</p>
</ul><p>
These macros simplify importing definitions from C to Scheme.
They expand into</p>
<p>
<tt>(define <i>name</i> (lookup-imported-binding <i>c-name</i>))</tt></p>
<p>
where <i>c-name</i> is as supplied for the second form.
For the first form <i>c-name</i> is derived from <i>name</i> by
replacing `<tt>-</tt>' with `<tt>_</tt>' and converting letters to lowercase.
For example, <tt>(import-definition my-foo)</tt> expands into</p>
<p>
<tt>(define my-foo (lookup-imported-binding &quot;my_foo&quot;))</tt></p>
<p>
</p>
<a name="node_sec_8.2.3"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.2.3">8.2.3&nbsp;&nbsp;Complete shared binding interface</a></h3>
<p></p>
<p>
There are a number of other Scheme functions related to shared bindings;
these are in the structure <tt>shared-bindings</tt>.</p>
<p>
</p>
<ul>
<li><p><tt>(shared-binding?<i> x</i>)&nbsp;-&gt;&nbsp;<i>boolean</i></tt><a name="node_idx_658"></a>
</p>
<li><p><tt>(shared-binding-name<i> shared-binding</i>)&nbsp;-&gt;&nbsp;<i>string</i></tt><a name="node_idx_660"></a>
</p>
<li><p><tt>(shared-binding-is-import?<i> shared-binding</i>)&nbsp;-&gt;&nbsp;<i>boolean</i></tt><a name="node_idx_662"></a>
</p>
<li><p><tt>(shared-binding-set!<i> shared-binding value</i>)</tt><a name="node_idx_664"></a>
</p>
<li><p><tt>(define-imported-binding<i> string value</i>)</tt><a name="node_idx_666"></a>
</p>
<li><p><tt>(lookup-exported-binding<i> string</i>)</tt><a name="node_idx_668"></a>
</p>
<li><p><tt>(undefine-imported-binding<i> string</i>)</tt><a name="node_idx_670"></a>
</p>
<li><p><tt>(undefine-exported-binding<i> string</i>)</tt><a name="node_idx_672"></a>
</p>
</ul><p></p>
<p>
<tt>Shared-binding?</tt> is the predicate for shared-bindings.
<tt>Shared-binding-name</tt> returns the name of a binding.
<tt>Shared-binding-is-import?</tt> is true if the binding was defined from C.
<tt>Shared-binding-set!</tt> changes the value of a binding.
<tt>Define-imported-binding</tt> and <tt>lookup-exported-binding</tt> are
Scheme versions of <tt>s48_define_exported_binding</tt>
and <tt>s48_lookup_imported_binding</tt>.
The two <tt>undefine-</tt> procedures remove bindings from the two tables.
They do nothing if the name is not found in the table.</p>
<p>
The following C macros correspond to the Scheme functions above.</p>
<p>
</p>
<ul>
<li><p><tt>int       S48_SHARED_BINDING_P(x)</tt>
</p>
<li><p><tt>int       S48_SHARED_BINDING_IS_IMPORT_P(s48_value s_b)</tt>
</p>
<li><p><tt>s48_value S48_SHARED_BINDING_NAME(s48_value s_b)</tt>
</p>
<li><p><tt>void      S48_SHARED_BINDING_SET(s48_value s_b, s48_value v)</tt>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_8.3"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.3">8.3&nbsp;&nbsp;Calling C functions from Scheme</a></h2>
<p></p>
<p>
There are three different ways to call C functions from Scheme, depending on
how the C function was obtained.</p>
<p>
</p>
<ul>
<li><p><tt>(call-imported-binding<i> binding arg<sub>0</sub> <tt>...</tt></i>)&nbsp;-&gt;&nbsp;<i>value</i></tt><a name="node_idx_674"></a>
</p>
</ul><p>
Each of these applies its first argument, a C function, to the rest of
the arguments.
For <tt>call-imported-binding</tt> the function argument must be an
imported binding.</p>
<p>
For all of these, the C function is passed the <i>arg<sub><em>i</em></sub></i> values
and the value returned is that returned by C procedure.
No automatic representation conversion occurs for either arguments or
return values.
Up to twelve arguments may be passed.
There is no method supplied for returning multiple values to
Scheme from C (or vice versa) (mainly because C does not have multiple return
values).</p>
<p>
Keyboard interrupts that occur during a call to a C function are ignored
until the function returns to Scheme (this is clearly a
problem; we are working on a solution).</p>
<p>
</p>
<ul>
<li><p><tt>(import-lambda-definition <i>name</i> (<i>formal</i> <tt>...</tt>))</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(syntax)<a name="node_idx_676"></a>
</p>
<li><p><tt>(import-lambda-definition <i>name</i> (<i>formal</i> <tt>...</tt>) <i>c-name</i>)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(syntax)
</p>
</ul><p>
These macros simplify importing functions from C.
They define <i>name</i> to be a function with the given formals that
applies those formals to the corresponding C binding.
<i>C-name</i>, if supplied, should be a string.
These expand into</p>
<p>
</p>
<pre class=verbatim>(define temp (lookup-imported-binding <i>c-name</i>))
(define <i>name</i>
  (lambda (<i>formal</i> <tt>...</tt>)
    (call-imported-binding temp <i>formal</i> <tt>...</tt>)))
</pre><p></p>
<p>

If <i>c-name</i> is not supplied, it is derived from <i>name</i> by converting
all letters to lowercase and replacing `<tt>-</tt>' with `<tt>_</tt>'.</p>
<p>
</p>
<a name="node_sec_8.4"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.4">8.4&nbsp;&nbsp;Dynamic loading</a></h2>
<p></p>
<p>
External code can be loaded into a running Scheme&nbsp;48 -- at least on
most variants of Unix and on Windows.  The required Scheme functions
are in the structure <tt>load-dynamic-externals</tt>.</p>
<p>
To be suitable for dynamic loading, the externals code must reside in
a shared object.  The shared object must define two functions:
</p>
<ul>
<li><p><tt>void s48_on_load(void)</tt>
</p>
<li><p><tt>void s48_on_reload(void)</tt>
</p>
</ul><p>
The <tt>s48_on_load</tt> is run upon loading the shared objects.  It
typically contains invocations of <tt>S48_EXPORT_FUNCTION</tt> to
make the functionality defined by the shared object known to
Scheme&nbsp;48.  Scheme&nbsp;48 calls <tt>s48_on_reload</tt> when it loads the
shared object for the second time, or some new version thereof.  (More
on that later.)  Most of the time, <tt>s48_on_reload</tt> will simply
call <tt>s48_on_load</tt>.</p>
<p>
For Linux, the following commands compile <tt>foo.c</tt> into a file
<tt>foo.so</tt> that can be loaded dynamically.
</p>
<pre class=verbatim>% gcc -c -o foo.o foo.c
% ld -shared -o foo.so foo.o
</pre><p>
The following procedures provide the basic functionality for loading
shared objects containing dynamic externals:
</p>
<ul>
<li><p><tt>(load-dynamic-externals<i> string plete?
rrepeat? rresume?</i>)&nbsp;-&gt;&nbsp;<i>dynamic-externals</i></tt><a name="node_idx_678"></a>
</p>
<li><p><tt>(unload-dynamic-externals<i> string</i>)&nbsp;-&gt;&nbsp;<i> dynamic-externals</i></tt><a name="node_idx_680"></a>
</p>
<li><p><tt>(reload-dynamic-externals<i> string</i>)</tt><a name="node_idx_682"></a>
</p>
</ul><p>
<tt>Load-dynamic-externals</tt> loads the
named shared objects.  The <i>plete?</i> argument determines whether
Scheme&nbsp;48 appends the OS-specific suffix (typically <tt>.so</tt> for
Unix, and <tt>.dll</tt> for Windows) to the name.  The <i>rrepeat?</i>
argument determines how <tt>load-dynamic-externals</tt> behaves if it is
called again with the same argument: If this is true, it reloads the
shared object (and calls its <tt>s48_on_reload</tt> function),
otherwise, it will not do anything.  The <i>rresume?</i>  argument
determines if an image subsequently dumped will try to load the shared
object again automatically.  (The shared objects will be loaded before
any record resumers run.)  <tt>Load-dynamic-externals</tt> returns a
handle identifying the shared object just loaded.</p>
<p>
<tt>Unload-dynamic-externals</tt> unloads the shared object associated
with the handle passed as its argument.  Note that this invalidates
all external bindings associated with the shared object; referring to
any of them will probably crash the program.</p>
<p>
<tt>Reload-dynamic-externals</tt> will reload the shared object named by
its argument and call its <tt>s48_on_reload</tt> function.</p>
<p>
</p>
<ul>
<li><p><tt>(import-dynamic-externals<i> string</i>)&nbsp;-&gt;&nbsp;<i>dynamic-externals</i></tt><a name="node_idx_684"></a>  
</p>
</ul><p>
This procedure represents the expected most usage for loading
dynamic-externals.  It is best explained by its definition:
</p>
<pre class=verbatim>(define (import-dynamic-externals name)
  (load-dynamic-externals name #t #f #t))
</pre><p></p>
<p>
</p>
<a name="node_sec_8.5"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.5">8.5&nbsp;&nbsp;Compatibility</a></h2>
<p>Scheme&nbsp;48's old <tt>external-call</tt> function is still available in the
structure
<tt>externals</tt>, which now also includes <tt>external-name</tt> and
<tt>external-value</tt>.
The old <tt>scheme48.h</tt> file has been renamed <tt>old-scheme48.h</tt>.</p>
<p>
Also, the old code for loading external code dynamically is still
available in the <tt>dynamic-externals</tt> structure, but will
probably disappear in a future release.</p>
<p>
</p>
<a name="node_sec_8.6"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.6">8.6&nbsp;&nbsp;Accessing Scheme data from C</a></h2>
<p></p>
<p>
The C header file <tt>scheme48.h</tt> provides
access to Scheme&nbsp;48 data structures.
The type <tt>s48_value</tt> is used for Scheme values.
When the type of a value is known, such as the integer returned
by <tt>vector-length</tt> or the boolean returned by <tt>pair?</tt>,
the corresponding C procedure returns a C value of the appropriate
type, and not a <tt>s48_value</tt>.
Predicates return <tt>1</tt> for true and <tt>0</tt> for false.</p>
<p>
</p>
<a name="node_sec_8.6.1"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.6.1">8.6.1&nbsp;&nbsp;Constants</a></h3>
<p></p>
<p>
The following macros denote Scheme constants:
</p>
<ul>
<li><p><tt>S48_FALSE</tt> is <code class=verbatim>#f</code>.
</p>
<li><p><tt>S48_TRUE</tt> is <code class=verbatim>#t</code>.
</p>
<li><p><tt>S48_NULL</tt> is the empty list.
</p>
<li><p><tt>S48_UNSPECIFIC</tt> is a value used for functions which have no
meaningful return value
(in Scheme&nbsp;48 this value returned by the nullary procedure <tt>unspecific</tt>
in the structure <tt>util</tt>).
</p>
<li><p><tt>S48_EOF</tt> is the end-of-file object
(in Scheme&nbsp;48 this value is returned by the nullary procedure <tt>eof-object</tt>
in the structure <tt>i/o-internal</tt>).
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_8.6.2"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.6.2">8.6.2&nbsp;&nbsp;Converting values</a></h3>
<p>The following macros and functions convert values between Scheme and C
representations.
The `extract' ones convert from Scheme to C and the `enter's go the other
way.</p>
<p>
</p>
<ul>
<li><p><tt>int       S48_EXTRACT_BOOLEAN(s48_value)</tt>
</p>
<li><p><tt>long      s48_extract_char(s48_value)</tt>
</p>
<li><p><tt>char *    s48_extract_string(s48_value)</tt>
</p>
<li><p><tt>char *    s48_extract_byte_vector(s48_value)</tt>
</p>
<li><p><tt>long      s48_extract_integer(s48_value)</tt>
</p>
<li><p><tt>double    s48_extract_double(s48_value)</tt>
</p>
<li><p><tt>s48_value S48_ENTER_BOOLEAN(int)</tt>
</p>
<li><p><tt>s48_value s48_enter_char(long)</tt>
</p>
<li><p><tt>s48_value s48_enter_byte_vector(char *, long)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>s48_value s48_enter_integer(long)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>s48_value s48_enter_double(double)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
</ul><p></p>
<p>
<tt>S48_EXTRACT_BOOLEAN</tt> is false if its argument is
<tt>#f</tt> and true otherwise.
<tt>S48_ENTER_BOOLEAN</tt> is <tt>#f</tt> if its argument is zero
and <tt>#t</tt> otherwise.</p>
<p>
The <tt>s48_extract_char</tt> function extracts the scalar value from
a Scheme character as a C <tt>long</tt>.  Conversely,
<tt>s48_enter_char</tt> creates a Scheme character from a scalar
value.  (Note that ASCII values are also scalar values.)</p>
<p>
The <tt>s48_extract_byte_vector</tt> function returns a
pointer to the actual
storage used by the byte vector.
These pointers are valid only until the next GC; see Section&nbsp;<a href="#node_sec_8.8">8.8</a>.</p>
<p>
The second argument to <tt>s48_enter_byte_vector</tt> is the length of
byte vector.</p>
<p>
<tt>s48_enter_integer()</tt> needs to allocate storage when
its argument is too large to fit in a Scheme&nbsp;48 fixnum.
In cases where the number is known to fit within a fixnum (currently 30 bits
including the sign), the following procedures can be used.
These have the disadvantage of only having a limited range, but
the advantage of never causing a garbage collection.
<tt>S48_FIXNUM_P</tt> is a macro that true if its argument is a fixnum
and false otherwise.</p>
<p>
</p>
<ul>
<li><p><tt>int       S48_TRUE_P(s48_value)</tt>
</p>
<li><p><tt>int       S48_FALSE_P(s48_value)</tt>
</p>
</ul><p></p>
<p>
<tt>S48_TRUE_P</tt> is true if its argument is <tt>S48_TRUE</tt>
and <tt>S48_FALSE_P</tt> is true if its argument is <tt>S48_FALSE</tt>.</p>
<p>
</p>
<ul>
<li><p><tt>int       S48_FIXNUM_P(s48_value)</tt>
</p>
<li><p><tt>long      s48_extract_fixnum(s48_value)</tt>
</p>
<li><p><tt>s48_value s48_enter_fixnum(long)</tt>
</p>
<li><p><tt>long      S48_MAX_FIXNUM_VALUE</tt>
</p>
<li><p><tt>long      S48_MIN_FIXNUM_VALUE</tt>
</p>
</ul><p></p>
<p>
An error is signalled if <tt>s48_extract_fixnum</tt>'s argument
is not a fixnum or if the argument to <tt>s48_enter_fixnum</tt> is less than
<tt>S48_MIN_FIXNUM_VALUE</tt> or greater than <tt>S48_MAX_FIXNUM_VALUE</tt>
( <tt>-</tt> 2<sup>29</sup> and 2<sup>29</sup> <tt>-</tt> 1 in the current system).</p>
<p>
</p>
<ul>
<li><p><tt>s48_value s48_enter_string_latin_1(char*);</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>s48_value s48_enter_string_latin_1_n(char*, long);</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>void      s48_copy_latin_1_to_string(char*, s48_value);</tt>
</p>
<li><p><tt>void      s48_copy_latin_1_to_string_n(char*, long, s48_value);</tt>
</p>
<li><p><tt>void      s48_copy_string_to_latin_1(s48_value, char*);</tt>
</p>
<li><p><tt>void      s48_copy_string_to_latin_1_n(s48_value, long, long, char*);</tt>
</p>
<li><p><tt>s48_value s48_enter_string_utf_8(char*);</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>s48_value s48_enter_string_utf_8_n(char*, long);</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>long      s48_string_utf_8_length(s48_value);</tt>
</p>
<li><p><tt>long      s48_string_utf_8_length_n(s48_value, long, long);</tt>
</p>
<li><p><tt>void      s48_copy_string_to_utf_8(s48_value, char*);</tt>
</p>
<li><p><tt>void      s48_copy_string_to_utf_8_n(s48_value, long, long, char*);</tt>
</p>
</ul><p>
The <tt>s48_enter_string_latin_1</tt> function creates a Scheme
string, initializing its contents from its NUL-terminated,
Latin-1-encoded argument.  The <tt>s48_enter_string_latin_1_n</tt>
function does the same, but allows specifying the length explicitly -- no NUL
terminator is necessary.</p>
<p>
The <tt>s48_copy_latin_1_to_string</tt> function copies
Latin-1-encoded characters from its first NUL-terminated argument to
the Scheme string that is its second argument.  The
<tt>s48_copy_latin_1_to_string_n</tt> does the same, but allows
specifying the number of characters explicitly.  The
<tt>s48_copy_string_to_latin_1</tt> function converts the
characters of the Scheme string specified as the first argument into
Latin-1 and writes them into the string specified as the second
argument.  (Note that it does not NUL-terminate the result.)  The
<tt>s48_copy_string_to_latin_1_n</tt> function does the same, but
allows specifying a starting index and a character count into the
source string.</p>
<p>
The <tt>s48_enter_string_utf_8</tt> function creates a Scheme
string, initializing its contents from its NUL-terminated,
UTF-8-encoded argument.  The <tt>s48_enter_string_utf_8_n</tt>
function does the same, but allows specifying the length
explicitly -- no NUL terminator is necessary.</p>
<p>
The <tt>s48_string_utf_8_length</tt> function computes the length
that the UTF-8 encoding of its argument (a Scheme string) would
occupy, not including NUL termination.  The
<tt>s48_string_utf_8_length</tt> function does the same, but allows
specifying a starting index and a count into the input string.</p>
<p>
The <tt>s48_copy_string_to_utf_8</tt> function converts the
characters of the Scheme string specified as the first argument into
UTF-8 and writes them into the string specified as the second
argument.  (Note that it does not NUL-terminate the result.)  The
<tt>s48_copy_string_to_utf_8_n</tt> function does the same, but
allows specifying a starting index and a character count into the
source string.</p>
<p>
</p>
<a name="node_sec_8.6.3"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.6.3">8.6.3&nbsp;&nbsp;C versions of Scheme procedures</a></h3>
<p>The following macros and procedures are C versions of Scheme procedures.
The names were derived by replacing `<tt>-</tt>' with `<tt>_</tt>',
`<tt>?</tt>' with `<tt>_P</tt>', and dropping `<tt>!</tt>.</p>
<p>
</p>
<ul>
<li><p><tt>int       S48_EQ_P(s48_value, s48_VALUE)</tt>
</p>
<li><p><tt>int       S48_CHAR_P(s48_value)</tt>
</p>
</ul><p>
</p>
<ul>
<li><p><tt>int       S48_PAIR_P(s48_value)</tt>
</p>
<li><p><tt>s48_value S48_CAR(s48_value)</tt>
</p>
<li><p><tt>s48_value S48_CDR(s48_value)</tt>
</p>
<li><p><tt>void      S48_SET_CAR(s48_value, s48_value)</tt>
</p>
<li><p><tt>void      S48_SET_CDR(s48_value, s48_value)</tt>
</p>
<li><p><tt>s48_value s48_cons(s48_value, s48_value)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>long      s48_length(s48_value)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>int       S48_VECTOR_P(s48_value)</tt> 
</p>
<li><p><tt>long      S48_VECTOR_LENGTH(s48_value)</tt> 
</p>
<li><p><tt>s48_value S48_VECTOR_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_VECTOR_SET(s48_value, long, s48_value)</tt> 
</p>
<li><p><tt>s48_value s48_make_vector(long, s48_value)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
</ul><p>
</p>
<ul>
<li><p><tt>int       S48_STRING_P(s48_value)</tt> 
</p>
<li><p><tt>long      S48_STRING_LENGTH(s48_value)</tt> 
</p>
<li><p><tt>long      S48_STRING_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_STRING_SET(s48_value, long, long)</tt> 
</p>
<li><p><tt>s48_value s48_make_string(long, char)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
</ul><p>
</p>
<ul>
<li><p><tt>int       S48_SYMBOL_P(s48_value)</tt> 
</p>
<li><p><tt>s48_value s48_SYMBOL_TO_STRING(s48_value)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>int       S48_BYTE_VECTOR_P(s48_value)</tt> 
</p>
<li><p><tt>long      S48_BYTE_VECTOR_LENGTH(s48_value)</tt> 
</p>
<li><p><tt>char      S48_BYTE_VECTOR_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_BYTE_VECTOR_SET(s48_value, long, int)</tt> 
</p>
<li><p><tt>s48_value s48_make_byte_vector(long, int)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_8.7"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.7">8.7&nbsp;&nbsp;Calling Scheme functions from C</a></h2>
<p></p>
<p>
External code that has been called from Scheme can call back to Scheme
procedures using the following function.</p>
<p>
</p>
<ul>
<li><p><tt>s48_value s48_call_scheme(s48_value p, long nargs, <tt>...</tt>)</tt>
</p>
</ul><p>
This calls the Scheme procedure <tt>p</tt> on <tt>nargs</tt>
arguments, which are passed as additional arguments to <tt>s48_call_scheme</tt>.
There may be at most twelve arguments.
The value returned by the Scheme procedure is returned by the C procedure.
Invoking any Scheme procedure may potentially cause a garbage collection.</p>
<p>
There are some complications that occur when mixing calls from C to Scheme
with continuations and threads.
C only supports downward continuations (via <tt>longjmp()</tt>).
Scheme continuations that capture a portion of the C stack have to follow the
same restriction.
For example, suppose Scheme procedure <tt>s0</tt> captures continuation <tt>a</tt>
and then calls C procedure <tt>c0</tt>, which in turn calls Scheme procedure
<tt>s1</tt>.
Procedure <tt>s1</tt> can safely call the continuation <tt>a</tt>, because that
is a downward use.
When <tt>a</tt> is called Scheme&nbsp;48 will remove the portion of the C stack used
by the call to <tt>c0</tt>.
On the other hand, if <tt>s1</tt> captures a continuation, that continuation
cannot be used from <tt>s0</tt>, because by the time control returns to
<tt>s0</tt> the C stack used by <tt>c0</tt> will no longer be valid.
An attempt to invoke an upward continuation that is closed over a portion
of the C stack will raise an exception.</p>
<p>
In Scheme&nbsp;48 threads are implemented using continuations, so the downward
restriction applies to them as well.
An attempt to return from Scheme to C at a time when the appropriate
C frame is not on top of the C stack will cause the current thread to
block until the frame is available.
For example, suppose thread <tt>t0</tt> calls a C procedure which calls back
to Scheme, at which point control switches to thread <tt>t1</tt>, which also
calls C and then back to Scheme.
At this point both <tt>t0</tt> and <tt>t1</tt> have active calls to C on the
C stack, with <tt>t1</tt>'s C frame above <tt>t0</tt>'s.
If thread <tt>t0</tt> attempts to return from Scheme to C it will block,
as its frame is not accessible.
Once <tt>t1</tt> has returned to C and from there to Scheme, <tt>t0</tt> will
be able to resume.
The return to Scheme is required because context switches can only occur while
Scheme code is running.
<tt>T0</tt> will also be able to resume if <tt>t1</tt> uses a continuation to
throw past its call to C.</p>
<p>
</p>
<a name="node_sec_8.8"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.8">8.8&nbsp;&nbsp;Interacting with the Scheme heap</a></h2>
<p>
</p>
<p>
Scheme&nbsp;48 uses a copying, precise garbage collector.
Any procedure that allocates objects within the Scheme&nbsp;48 heap may trigger
a garbage collection.
Variables bound to values in the Scheme&nbsp;48 heap need to be registered with
the garbage collector so that the value will be retained and so that the
variables will be updated if the garbage collector moves the object.
The garbage collector has no facility for updating pointers to the interiors
of objects, so such pointers, for example the ones returned by
<tt>s48_extract_byte_vector</tt>, will likely become invalid when a garbage collection
occurs.</p>
<p>
</p>
<a name="node_sec_8.8.1"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.8.1">8.8.1&nbsp;&nbsp;Registering objects with the GC</a></h3>
<p></p>
<p>
A set of macros are used to manage the registration of local variables with the
garbage collector.</p>
<p>
</p>
<ul>
<li><p><tt>S48_DECLARE_GC_PROTECT(<em>n</em>)</tt>
</p>
<li><p><tt>void S48_GC_PROTECT_<em>n</em>(s48_value<sub>1</sub>, <tt>...</tt>, s48_value<sub><em>n</em></sub>)</tt>
</p>
<li><p><tt>void S48_GC_UNPROTECT()</tt>
</p>
</ul><p></p>
<p>
<tt>S48_DECLARE_GC_PROTECT(<em>n</em>)</tt>, where  1<u>&lt;</u> <em>n</em><u>&lt;</u> 9, allocates
storage for registering <em>n</em> variables.
At most one use of <tt>S48_DECLARE_GC_PROTECT</tt> may occur in a
block.
<tt>S48_GC_PROTECT_<em>n</em>(<em>v</em><sub>1</sub>, <tt>...</tt>, <em>v</em><sub><em>n</em></sub>)</tt> registers the
<em>n</em> variables (l-values) with the garbage collector.
It must be within scope of a <tt>S48_DECLARE_GC_PROTECT(<em>n</em>)</tt>
and be before any code which can cause a GC.
<tt>S48_GC_UNPROTECT</tt> removes the block's protected variables from
the garbage collector's list.
It must be called at the end of the block after 
any code which may cause a garbage collection.
Omitting any of the three may cause serious and
hard-to-debug problems.
Notably, the garbage collector may relocate an object and
invalidate <tt>s48_value</tt> variables which are not protected.</p>
<p>
A <tt>gc-protection-mismatch</tt> exception is raised if, when a C
procedure returns to Scheme, the calls
to <tt>S48_GC_PROTECT()</tt> have not been matched by an equal number of
calls to <tt>S48_GC_UNPROTECT()</tt>.</p>
<p>
Global variables may also be registered with the garbage collector.</p>
<p>
</p>
<ul>
<li><p><tt>void * S48_GC_PROTECT_GLOBAL(<i>value</i>)</tt>
</p>
<li><p><tt>void S48_GC_UNPROTECT_GLOBAL(void * handle)</tt>
</p>
</ul><p></p>
<p>
<tt>S48_GC_PROTECT_GLOBAL</tt> permanently registers the
variable <i>value</i> (an l-value of type <tt>s48_value</tt>) with the
garbage collector.  It returns a handle pointer for use as an argument
to <tt>S48_GC_UNPROTECT_GLOBAL</tt>, which unregisters the variable
again.</p>
<p>
</p>
<a name="node_sec_8.8.2"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.8.2">8.8.2&nbsp;&nbsp;Keeping C data structures in the Scheme heap</a></h3>
<p></p>
<p>
C data structures can be kept in the Scheme heap by embedding them
inside byte vectors.
The following macros can be used to create and access embedded C objects.</p>
<p>
</p>
<ul>
<li><p><tt>s48_value S48_MAKE_VALUE(type)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>type      S48_EXTRACT_VALUE(s48_value, type)</tt>
</p>
<li><p><tt>type *    S48_EXTRACT_VALUE_POINTER(s48_value, type)</tt>
</p>
<li><p><tt>void      S48_SET_VALUE(s48_value, type, value)</tt>
</p>
</ul><p></p>
<p>

<tt>S48_MAKE_VALUE</tt> makes a byte vector large enough to hold an object
whose type is <i>type</i>.
<tt>S48_EXTRACT_VALUE</tt> returns the contents of a byte vector cast to
<i>type</i>, and <tt>S48_EXTRACT_VALUE_POINTER</tt> returns a pointer
to the contents of the byte vector.
The value returned by <tt>S48_EXTRACT_VALUE_POINTER</tt> is valid only until
the next garbage collection.</p>
<p>
<tt>S48_SET_VALUE</tt> stores <tt>value</tt> into the byte vector.</p>
<p>
</p>
<p>
</p>
<a name="node_sec_8.8.3"></a>
<h3><a href="manual-Z-H-2.html#node_toc_node_sec_8.8.3">8.8.3&nbsp;&nbsp;C code and heap images</a></h3>
<p></p>
<p>
Scheme&nbsp;48 uses dumped heap images to restore a previous system state.
The Scheme&nbsp;48 heap is written into a file in a machine-independent and
operating-system-independent format.
The procedures described above may be used to create objects in the
Scheme heap that contain information specific to the current
machine, operating system, or process.
A heap image containing such objects may not work correctly
when resumed.</p>
<p>
To address this problem, a record type may be given a `resumer'
procedure.
On startup, the resumer procedure for a type is applied to each record of
that type in the image being restarted.
This procedure can update the record in a manner appropriate to
the machine, operating system, or process used to resume the
image.</p>
<p>
</p>
<ul>
<li><p><tt>(define-record-resumer<i> record-type procedure</i>)</tt><a name="node_idx_686"></a>
</p>
</ul><p></p>
<p>
<tt>Define-record-resumer</tt> defines <i>procedure</i>,
which should accept one argument, to be the resumer for
<i>record-type</i>.
The order in which resumer procedures are called is not specified.</p>
<p>
The <i>procedure</i> argument to <tt>define-record-resumer</tt> may
be <tt>#f</tt>, in which case records of the given type are
not written out in heap images.
When writing a heap image any reference to such a record is replaced by
the value of the record's first field, and an exception is raised
after the image is written.</p>
<p>
</p>
<a name="node_sec_8.9"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.9">8.9&nbsp;&nbsp;Using Scheme records in C code</a></h2>
<p>External modules can create records and access their slots
positionally.</p>
<p>
</p>
<ul>
<li><p><tt>s48_value s48_make_record(s48_value)</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(may GC)
</p>
<li><p><tt>int       S48_RECORD_P(s48_value)</tt> 
</p>
<li><p><tt>s48_value S48_RECORD_TYPE(s48_value)</tt> 
</p>
<li><p><tt>s48_value S48_RECORD_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_RECORD_SET(s48_value, long, s48_value)</tt> 
</p>
</ul><p>
The argument to <tt>s48_make_record</tt> should be a shared binding
whose value is a record type.
In C the fields of Scheme records are only accessible via offsets,
with the first field having offset zero, the second offset one, and
so forth.
If the order of the fields is changed in the Scheme definition of the
record type the C code must be updated as well.</p>
<p>
For example, given the following record-type definition
</p>
<pre class=verbatim>(define-record-type thing :thing
  (make-thing a b)
  thing?
  (a thing-a)
  (b thing-b))
</pre><p>
the identifier <tt>:thing</tt> is bound to the record type and can
be exported to C:
</p>
<pre class=verbatim>(define-exported-binding &quot;thing-record-type&quot; :thing)
</pre><p>
<tt>Thing</tt> records can then be made in C:
</p>
<pre class=verbatim>static s48_value
  thing_record_type_binding = S48_FALSE;

void initialize_things(void)
{
  S48_GC_PROTECT_GLOBAL(thing_record_type_binding);
  thing_record_type_binding =
     s48_get_imported_binding(&quot;thing-record-type&quot;);
}

s48_value make_thing(s48_value a, s48_value b)
{
  s48_value thing;
  s48_DECLARE_GC_PROTECT(2);

  S48_GC_PROTECT_2(a, b);

  thing = s48_make_record(thing_record_type_binding);
  S48_RECORD_SET(thing, 0, a);
  S48_RECORD_SET(thing, 1, b);

  S48_GC_UNPROTECT();

  return thing;
}
</pre><p>
Note that the variables <tt>a</tt> and <tt>b</tt> must be protected
against the possibility of a garbage collection occuring during
the call to <tt>s48_make_record()</tt>.</p>
<p>
</p>
<a name="node_sec_8.10"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.10">8.10&nbsp;&nbsp;Raising exceptions from external code</a></h2>
<p></p>
<p>
The following macros explicitly raise certain errors, immediately
returning to Scheme&nbsp;48.
Raising an exception performs all
necessary clean-up actions to properly return to Scheme&nbsp;48, including
adjusting the stack of protected variables.</p>
<p>
</p>
<ul>
<li><p><tt>s48_raise_scheme_exception(int type, int nargs, <tt>...</tt>)</tt>
</p>
</ul><p></p>
<p>
<tt>s48_raise_scheme_exception</tt> is the base procedure for
raising exceptions.
<tt>type</tt> is the type of exception, and should be one of the
<tt>S48_EXCEPTION_</tt><tt>...</tt>constants defined in <tt>scheme48arch.h</tt>.
<tt>nargs</tt> is the number of additional values to be included in the
exception; these follow the <tt>nargs</tt> argument and should all have
type <tt>s48_value</tt>.
<tt>s48_raise_scheme_exception</tt> never returns.</p>
<p>
The following procedures are available for raising particular
types of exceptions.
Like <tt>s48_raise_scheme_exception</tt> these never return.</p>
<p>
</p>
<ul>
<li><p><tt>s48_raise_argument_type_error(s48_value)</tt>
</p>
<li><p><tt>s48_raise_argument_number_error(int nargs, int min, int max)</tt>
</p>
<li><p><tt>s48_raise_range_error(long value, long min, long max)</tt>
</p>
<li><p><tt>s48_raise_closed_channel_error()</tt>
</p>
<li><p><tt>s48_raise_os_error(int errno)</tt>
</p>
<li><p><tt>s48_raise_out_of_memory_error()</tt>
</p>
</ul><p></p>
<p>
An argument type error indicates that the given value is of the wrong
type.
An argument number error is raised when the number of arguments, <tt>nargs</tt>,
should be, but isn't, between <tt>min</tt> and <tt>max</tt>, inclusive.
Similarly, a range error indicates that <tt>value</tt> is not between
between <tt>min</tt> and <tt>max</tt>, inclusive.</p>
<p>
The following macros raise argument type errors if their argument does not
have the required type.
<tt>S48_CHECK_BOOLEAN</tt> raises an error if its argument is neither
<tt>#t</tt> or <tt>#f</tt>.</p>
<p>
</p>
<ul>
<li><p><tt>void S48_CHECK_BOOLEAN(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_SYMBOL(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_PAIR(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_STRING(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_INTEGER(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_CHANNEL(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_BYTE_VECTOR(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_RECORD(s48_value)</tt>
</p>
<li><p><tt>void S48_CHECK_SHARED_BINDING(s48_value)</tt>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_8.11"></a>
<h2><a href="manual-Z-H-2.html#node_toc_node_sec_8.11">8.11&nbsp;&nbsp;Unsafe functions and macros</a></h2>
<p>All of the C procedures and macros described above check that their
arguments have the appropriate types and that indexes are in range.
The following procedures and macros are identical to those described
above, except that they do not perform type and range checks.
They are provided for the purpose of writing more efficient code;
their general use is not recommended.</p>
<p>
</p>
<ul>
<li><p><tt>long      S48_UNSAFE_EXTRACT_CHAR(s48_value)</tt>
</p>
<li><p><tt>s48_value S48_UNSAFE_ENTER_CHAR(long)</tt>
</p>
<li><p><tt>long      S48_UNSAFE_EXTRACT_INTEGER(s48_value)</tt>
</p>
<li><p><tt>long      S48_UNSAFE_EXTRACT_DOUBLE(s48_value)</tt>
</p>
</ul><p>
</p>
<ul>
<li><p><tt>long      S48_UNSAFE_EXTRACT_FIXNUM(s48_value)</tt>
</p>
<li><p><tt>s48_value S48_UNSAFE_ENTER_FIXNUM(long)</tt>
</p>
</ul><p>
</p>
<ul>
<li><p><tt>s48_value S48_UNSAFE_CAR(s48_value)</tt>
</p>
<li><p><tt>s48_value S48_UNSAFE_CDR(s48_value)</tt>
</p>
<li><p><tt>void      S48_UNSAFE_SET_CAR(s48_value, s48_value)</tt>
</p>
<li><p><tt>void      S48_UNSAFE_SET_CDR(s48_value, s48_value)</tt>
</p>
</ul><p>
</p>
<ul>
<li><p><tt>long      S48_UNSAFE_VECTOR_LENGTH(s48_value)</tt> 
</p>
<li><p><tt>s48_value S48_UNSAFE_VECTOR_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_UNSAFE_VECTOR_SET(s48_value, long, s48_value)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>long      S48_UNSAFE_STRING_LENGTH(s48_value)</tt> 
</p>
<li><p><tt>char      S48_UNSAFE_STRING_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_UNSAFE_STRING_SET(s48_value, long, char)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>s48_value S48_UNSAFE_SYMBOL_TO_STRING(s48_value)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>long      S48_UNSAFE_BYTE_VECTOR_LENGTH(s48_value)</tt> 
</p>
<li><p><tt>char      S48_UNSAFE_BYTE_VECTOR_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_UNSAFE_BYTE_VECTOR_SET(s48_value, long, int)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>s48_value S48_UNSAFE_SHARED_BINDING_REF(s48_value s_b)</tt>
</p>
<li><p><tt>int       S48_UNSAFE_SHARED_BINDING_P(x)</tt>
</p>
<li><p><tt>int       S48_UNSAFE_SHARED_BINDING_IS_IMPORT_P(s48_value s_b)</tt>
</p>
<li><p><tt>s48_value S48_UNSAFE_SHARED_BINDING_NAME(s48_value s_b)</tt>
</p>
<li><p><tt>void      S48_UNSAFE_SHARED_BINDING_SET(s48_value s_b, s48_value value)</tt>
</p>
</ul><p>
</p>
<ul>
<li><p><tt>s48_value S48_UNSAFE_RECORD_TYPE(s48_value)</tt> 
</p>
<li><p><tt>s48_value S48_UNSAFE_RECORD_REF(s48_value, long)</tt> 
</p>
<li><p><tt>void      S48_UNSAFE_RECORD_SET(s48_value, long, s48_value)</tt> 
</p>
</ul><p>
</p>
<ul>
<li><p><tt>type      S48_UNSAFE_EXTRACT_VALUE(s48_value, type)</tt>
</p>
<li><p><tt>type *    S48_UNSAFE_EXTRACT_VALUE_POINTER(s48_value, type)</tt>
</p>
<li><p><tt>void      S48_UNSAFE_SET_VALUE(s48_value, type, value)</tt>
</p>
</ul><p></p>
<p>


</p>
<div align=right class=navigation><i>[Go to <span><a href="manual.html">first</a>, <a href="manual-Z-H-9.html">previous</a></span><span>, <a href="manual-Z-H-11.html">next</a></span> page<span>; &nbsp;&nbsp;</span><span><a href="manual-Z-H-2.html#node_toc_start">contents</a></span><span><span>; &nbsp;&nbsp;</span><a href="manual-Z-H-13.html#node_index_start">index</a></span>]</i></div>
<p></p>
</div>
</body>
</html>
